﻿using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Qianke.Core.Common.Interface;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Entities.Caching;
using Volo.Abp.Domain.Repositories;

namespace Qianke.Core.Saas.Application.Common
{
    public static class DbSetExtensions
    {
        public static void DeleteFromOrganId<TEntity>(this DbSet<TEntity> dbSet, long organId)
            where TEntity : class, IHasOrganId
        {
            dbSet.RemoveRange(dbSet.Where(u => u.OrganId == organId));
        }

        public static async Task<string> GetName<TEntity, TKey>(this DbSet<TEntity> dbSet, TKey id)
            where TEntity : class, IEntity<TKey>, IHasName
        {
            var lazyServiceProvider = dbSet.GetService<IAbpLazyServiceProvider>();
            var entityCache = lazyServiceProvider.GetService((IEntityCache<TEntity, TKey>)null);
            if (entityCache != null)
            {
                var entity = await entityCache.GetAsync(id);
                return entity?.Name ?? "";
            }
            var keyName = $"{typeof(TEntity).Name}_{id}_Name";
            var distributeCache = dbSet.GetService<IDistributedCache<string>>();
            return await distributeCache.GetOrAddAsync(keyName, async () =>
            {
                return await dbSet.Where(u => u.Id.Equals(id)).Select(u => u.Name).FirstOrDefaultAsync();
            }, () => new Microsoft.Extensions.Caching.Distributed.DistributedCacheEntryOptions()
            {
                AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30)
            });

        }

        public static async Task UpdateCacheName<TEntity, TPrimaryKey>(this IRepository<TEntity, TPrimaryKey> repository, TEntity entity)
            where TEntity : class, IEntity<TPrimaryKey>
        {
            if(entity is IHasName hasNameEntity)
            {
                var keyName = $"{typeof(TEntity).Name}_{entity.Id}_Name";
                var db = await repository.GetDbContextAsync();
                var distributeCache = db.GetService<IDistributedCache<string>>();
                await distributeCache.SetAsync(keyName, hasNameEntity.Name);
            }
        }


    }
}
